package timing.ukulele.third.service.common;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import org.springframework.stereotype.Service;
import timing.ukulele.common.data.ResponseCode;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.common.dictionary.ThirdPartyTypeEnum;
import timing.ukulele.common.dictionary.YesOrNoEnum;
import timing.ukulele.data.portal.view.UserVO;
import timing.ukulele.data.third.data.common.PhoneRegisterDTO;
import timing.ukulele.data.third.data.common.SysThirdPartyUserDTO;
import timing.ukulele.data.third.view.common.SysThirdPartyUserVO;
import timing.ukulele.facade.portal.feign.UserFeignFacade;
import timing.ukulele.third.config.mp.WxMpConfiguration;
import timing.ukulele.third.convertor.common.SysThirdPartyUserConverter;
import timing.ukulele.third.mapper.sys.SysThirdPartyUserMapper;
import timing.ukulele.third.persistent.common.SysThirdPartyUser;
import timing.ukulele.third.persistent.weixin.WxApp;
import timing.ukulele.third.service.weixin.WxAppService;

import java.util.List;

/**
 * 第三方用户
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysThirdPartyUserService extends ServiceImpl<SysThirdPartyUserMapper, SysThirdPartyUser> {

    private final WxAppService wxAppService;

    @Resource
    private UserFeignFacade userFeignFacade;

    /**
     * 根据平台类型和平台用户标识获取第三方用户
     * @param platSource
     * @param platId
     * @return
     */
    public SysThirdPartyUserVO getByPlatSourceAndId(Integer platSource, String appId, String platId) {
        SysThirdPartyUser one = this.lambdaQuery()
                .eq(SysThirdPartyUser::getPlatSource, platSource)
                .eq(SysThirdPartyUser::getAppId, appId)
                .eq(SysThirdPartyUser::getPlatId, platId)
                .one();
        return SysThirdPartyUserConverter.INSTANCE.p2v(one);
    }

    /**
     * 分页列表
     * @param dto
     * @return
     */
    public IPage<SysThirdPartyUserVO> pageList(SysThirdPartyUserDTO dto) {
        Page<SysThirdPartyUser> pageParam = new Page<>(dto.getCurrent(), dto.getPageSize());
        Page<SysThirdPartyUser> page = this.lambdaQuery()
                .eq(StrUtil.isNotBlank(dto.getUsername()), SysThirdPartyUser::getUsername, dto.getUsername())
                .eq(ObjectUtil.isNotNull(dto.getPlatSource()), SysThirdPartyUser::getPlatSource, dto.getPlatSource())
                .eq(StrUtil.isNotBlank(dto.getPlatId()), SysThirdPartyUser::getPlatId, dto.getPlatId())
                .eq(StrUtil.isNotBlank(dto.getUnionId()), SysThirdPartyUser::getUnionId, dto.getUnionId())
                .page(pageParam);
        List<SysThirdPartyUserVO> list = SysThirdPartyUserConverter.INSTANCE.p2vList(page.getRecords());
        Page<SysThirdPartyUserVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        voPage.setRecords(list);
        return voPage;
    }

    /**
     * 根据输入手机号注册用户
     * @param phoneRegisterDTO
     * @return
     */
    public ResponseData<String> phoneRegister(PhoneRegisterDTO phoneRegisterDTO) {
        // 查询第三方用户
        String platId = null;
        String unionId = null;
        if(ThirdPartyTypeEnum.hasValue(phoneRegisterDTO.getThirdType())) {
            return ResponseData.error("暂不支持该平台");
        }
        if (ThirdPartyTypeEnum.WX_MP.getValue().equals(phoneRegisterDTO.getThirdType())) {
            // 是否存在appID
            String appId = phoneRegisterDTO.getAppId();
            if (StrUtil.isBlank(appId)) {
                WxApp wxApp = wxAppService.lambdaQuery().eq(WxApp::getIsDefault, YesOrNoEnum.YES.getValue()).one();
                if(wxApp == null) {
                    return ResponseData.error("微信公众号配置不存在");
                }
                appId = wxApp.getAppId();
            }
            WxOAuth2Service oAuth2Service = WxMpConfiguration.getMpServiceByAppId(appId).getOAuth2Service();
            WxOAuth2AccessToken accessToken = null;
            try {
                accessToken = oAuth2Service.getAccessToken(phoneRegisterDTO.getCode());
            } catch (WxErrorException e) {
                return ResponseData.error("获取微信账号失败");
            }
            platId = accessToken.getOpenId();
            unionId = accessToken.getUnionId();
        }
        if(platId == null) {
            return ResponseData.error("获取第三方用户信息失败,无法进行注册");
        }
        // 查询是否存在第三方用户，如果没有则进行添加
        SysThirdPartyUser sysThirdPartyUser = this.lambdaQuery()
                .eq(SysThirdPartyUser::getPlatSource, phoneRegisterDTO.getThirdType())
                .eq(SysThirdPartyUser::getPlatId, platId).one();
        if(sysThirdPartyUser == null) {
            SysThirdPartyUser insert = new SysThirdPartyUser();
            insert.setPlatSource(phoneRegisterDTO.getThirdType());
            insert.setAppId(phoneRegisterDTO.getAppId());
            insert.setPlatId(platId);
            insert.setUnionId(unionId);
            this.save(insert);
        }

        // 注册用户
        UserVO userVO = new UserVO();
        userVO.setUsername(RandomUtil.randomString(12));
        userVO.setPhone(phoneRegisterDTO.getPhone());
        userVO.setPlat(phoneRegisterDTO.getThirdType());
        userVO.setPlatId(platId);
        userVO.setUnionId(unionId);
        ResponseData<String> registerUserResponseData = userFeignFacade.registerUserByThird(userVO);
        if (!registerUserResponseData.getCode().equals(ResponseCode.SUCCESS.getCode())) {
            return ResponseData.error(registerUserResponseData.getMessage());
        }

        return ResponseData.success(registerUserResponseData.getData());
    }

}
